package linker

import (
	"log"
	"net"
	"test/protocol"
	"test/util"
	"time"
)

//Handlerclient tcp server handl connection
func handlerclient(conn *net.TCPConn, pro protocol.Protocol, rtu int16) (result int) {
	message := make(chan []byte)

	defer func() {
		log.Println("linker: close connection")
		conn.Close()
		result = LinkerQuit
		if e := recover(); e != nil {
			log.Printf("Panicking %s\r\n", e)
		}
		message = nil
	}()
	go protocolhandler(conn, pro, rtu, message)
	for {
		buf := make([]byte, 1024)
		time.Sleep(15 * time.Millisecond)
		n, err := conn.Read(buf)
		if err != nil {
			log.Println(err)
			return
		}
		message <- buf[0:n]
		buf = nil
	}
}

//protocolhandler
func protocolhandler(conn *net.TCPConn, pro protocol.Protocol, rtu int16, message chan []byte) {
	pro.Init(conn, rtu)
	defer pro.Delete()
	var isQuit bool
	var timeCount int
	for {
		time.Sleep(time.Millisecond * 10)
		select {
		case data, open := <-message:
			if !open { //linker层关闭chan，protocol层退出
				isQuit = true
			} else {
				log.Println(conn.RemoteAddr().String() + " recv:")
				util.Printpacket(string(data))
				timeCount = 0
				pro.Handler(string(data))
			}
			break
		case <-time.After(time.Millisecond * 10):
			result := pro.Run()
			if result >= protocol.ProtocolQuit {
				timeCount = 0
				isQuit = true
			}
			if timeCount > LongTimeNoDataFromLinker*100 {
				timeCount = 0
				isQuit = true
				conn.Close()
			}
			timeCount++
			break
		}
		if isQuit {
			log.Println(conn.RemoteAddr().String() + " protocol handler quit")
			break
		}
	}
	close(message)
}
